#include "Pawn.h"

#include "SquareValueBoard.h"

using namespace Rorn::Chess::TheCorruptRook;

Pawn::Pawn(void)
{
}

Pawn::~Pawn(void)
{
}

/*static*/ double Pawn::CalculateScore(const Position& position, Player::Type player, const Square& square)
{
	double materialScore = 1.0;
	double advancementScore = 0.1 * (static_cast<double>(square.GetRank()) - 1.0);
	// TODO backward-ness
	// TODO passed-ness
	// TODO isolated-ness
	std::vector<Square> visibleAttackSquares;
	GetVisibleAttackSquares(position, player, square, visibleAttackSquares);
	double visibilityScore = 0;
	for(std::vector<Square>::const_iterator sqaureIter = visibleAttackSquares.begin() ; sqaureIter != visibleAttackSquares.end() ; ++sqaureIter)
		visibilityScore += SquareValueBoard::GetSquareValue(*sqaureIter);

	return materialScore + advancementScore + visibilityScore;
}

/*static*/ void Pawn::GetLegalMoves(const Position& position, Player::Type player, const Square& startSquare, std::vector<MoveTreeNode>& legalMoves, int depth)
{
	// Forward one square
	Square squareForwardOne(startSquare.GetRank() + 1, startSquare.GetFile());
	if( (position.GetPiece(player, squareForwardOne) == 0) )
	{
		legalMoves.emplace_back(MoveTreeNode(position, Player::GetOpposite(player), depth, startSquare, squareForwardOne));
	}

	// Forward two squares
	Square squareForwardTwo(startSquare.GetRank() + 2, startSquare.GetFile());
	if( (startSquare.GetRank() == 1) && 
		(position.GetPiece(player, squareForwardTwo) == 0) &&
		(position.GetPiece(player, squareForwardOne) == 0) )
	{
		legalMoves.emplace_back(MoveTreeNode(position, Player::GetOpposite(player), depth, startSquare, squareForwardTwo));
	}

	// Attack left
	Square squareAttackLeft(startSquare.GetRank() + 1, startSquare.GetFile() - 1);
	if( Square::IsOnBoard(squareAttackLeft) &&
		(position.GetPiece(player, squareAttackLeft) < 0) )
	{
		legalMoves.emplace_back(MoveTreeNode(position, Player::GetOpposite(player), depth, startSquare, squareAttackLeft));
	}

	// Attack right
	Square squareAttackRight(startSquare.GetRank() + 1, startSquare.GetFile() + 1);
	if( Square::IsOnBoard(squareAttackRight) &&
		(position.GetPiece(player, squareAttackRight) < 0) )
	{
		legalMoves.emplace_back(MoveTreeNode(position, Player::GetOpposite(player), depth, startSquare, squareAttackRight));
	}
}

/*static*/ void Pawn::GetVisibleAttackSquares(const Position& position, Player::Type player, const Square& square, std::vector<Square>& visibleAttackSquares)
{
	// Attack left
	Square squareAttackLeft(square.GetRank() + 1, square.GetFile() - 1);
	if( Square::IsOnBoard(squareAttackLeft) &&
		(position.GetPiece(player, squareAttackLeft) <= 0) )
	{
		visibleAttackSquares.push_back(squareAttackLeft);
	}

	// Attack right
	Square squareAttackRight(square.GetRank() + 1, square.GetFile() + 1);
	if( Square::IsOnBoard(squareAttackRight) &&
		(position.GetPiece(player, squareAttackRight) <= 0) )
	{
		visibleAttackSquares.push_back(squareAttackRight);
	}
}